package com.ruoyi.luban.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.nacos.shaded.io.grpc.internal.JsonUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.luban.domain.PWxLoginUser;
import com.ruoyi.luban.domain.WXUserLoginInfo;
import com.ruoyi.luban.domain.dto.RegistAndBindUserDto;
import com.ruoyi.luban.domain.vo.LoginUserAndTokenVo;
import com.ruoyi.luban.domain.vo.WxLoginUserVo;
import com.ruoyi.luban.service.IPWxLoginUserService;
import com.ruoyi.luban.service.IPWxUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ResponseBody
@RequestMapping("/wx")
@Controller
public class WXController extends WXBaseController {
    @Value("${wx.appid}")
    private String appidWX;
    @Value("${wx.key}")
    private String keyWX;
    @Autowired
    private IPWxUserService ipWxUserService;
    @Autowired
    private IPWxLoginUserService ipWxLoginUserService;
    @Autowired
    WxMaService wxMaService;

    /**
     * @param params
     * @return
     * @throws Exception
     */
    @PostMapping("/login")
    @ResponseBody
    @Log(title = "微信登录", businessType = BusinessType.INSERT)
    public AjaxResult login(@RequestHeader(value = "token",defaultValue = "test") String token,@RequestBody Map<String,Object> params){
//        LoginUserAndTokenVo info = this.getLoginUserInfo2(token);
//        if (info != null){
//            return success(info);
//        }
        String code = params.get("code")==null?"":params.get("code").toString();
        if(!StringUtils.isNotBlank(code) && params.get("openId")==null) {
            return error("系统繁忙,请稍后重试!");
        }
        String openId = params.get("openId")==null?"":params.get("openId").toString();
        try {
           LoginUserAndTokenVo loginUserAndTokenVo = ipWxUserService.loginWithWxFlow(code,openId);
           setLoginUserInfo2(loginUserAndTokenVo);
           setRegisters(loginUserAndTokenVo.getMaOpenId(),loginUserAndTokenVo);
           return success(loginUserAndTokenVo);
        }catch(Exception e) {
            e.printStackTrace();
            logger.debug(e.getMessage(),e);
        }
        return error("系统繁忙,请稍后重试!");
    }

    /**
     * @param params
     * @return
     * @throws Exception
     */
    @PostMapping("/saveSubscribeStatus")
    @ResponseBody
    @Log(title = "保存微信用户订阅消息状态", businessType = BusinessType.INSERT)
    public AjaxResult saveSubscribeStatus(@RequestHeader(value = "token",defaultValue = "test") String token,@RequestBody Map<String,Object> params){
        LoginUserAndTokenVo info = this.getLoginUserInfo2(token);
        if (info != null){
            error_to_login();
        }
        String subscribeStatus = params.get("subscribeStatus")==null?"":params.get("subscribeStatus").toString();
        try {
            LoginUserAndTokenVo loginUserAndTokenVo = ipWxUserService.saveSubscribeStatus(info,subscribeStatus);
            setLoginUserInfo2(loginUserAndTokenVo);
            return success(loginUserAndTokenVo);
        }catch(Exception e) {
            e.printStackTrace();
            logger.debug(e.getMessage(),e);
        }
        return error("系统繁忙,请稍后重试!");
    }


    /**
     * @param token
     * @return
     * @throws Exception
     */
    @GetMapping("/getUser")
    @ResponseBody
    @Log(title = "获取登录用户信息", businessType = BusinessType.INSERT)
    public AjaxResult login(@RequestHeader(value = "token",defaultValue = "test")  String token){
        LoginUserAndTokenVo info = this.getLoginUserInfo2(token);
        if (info == null){
            return error_to_login();
        }
        return success(info);
    }
    // 通过微信进行注册绑定
    @PostMapping("/registAndBind")
    @Log(title = "通过微信进行注册绑定", businessType = BusinessType.INSERT)
    public AjaxResult registAndBind(@RequestHeader(value = "token",defaultValue = "test") String token,@RequestBody RegistAndBindUserDto registAndBindParam) throws Exception {
        logger.info("regist_and_bind:请求头{}", token);
        logger.info("regist_and_bind:注册用户传递参数{}", JSONObject.toJSON(registAndBindParam));
        LoginUserAndTokenVo loginUserAndTokenVo = null;
        try {
            LoginUserAndTokenVo info = this.getLoginUserInfo2(token);
            logger.info("regist_and_bind:登录用户头{}", info);
            if(info == null && registAndBindParam.getMaOpenId() != null){
                //请求头拿不到登录参数
                info = this.getLoginUserInfo2(registAndBindParam.getMaOpenId());
                logger.info("去code:获取登录信息{}", info);
            }
            loginUserAndTokenVo = ipWxUserService.registWithWxFlow(info,registAndBindParam);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }
        if(loginUserAndTokenVo != null) {
            setLoginUserInfo2(loginUserAndTokenVo);
            return success(loginUserAndTokenVo);
        }
        return error("注册失败");
    }
    
    @PostMapping("/updateUserInfo")
    public AjaxResult updateUserInfo(@RequestBody PWxLoginUser pWxLoginUser,@RequestHeader(value = "token",defaultValue = "test") String token){
        LoginUserAndTokenVo loginUserAndTokenVo = null;
        LoginUserAndTokenVo info = this.getLoginUserInfo2(token);
        logger.info("regist_and_bind:登录用户头{}", info);
        if (info == null){
            return error_to_login();
        }
        pWxLoginUser.setId(info.getLoginUser().getLoginUserId());
        int i = ipWxLoginUserService.updatePWxLoginUser(pWxLoginUser);
        if(loginUserAndTokenVo != null && i>0) {
            loginUserAndTokenVo.getLoginUser().setLoginUrl(pWxLoginUser.getLoginUrl());
            setLoginUserInfo2(loginUserAndTokenVo);
            return success(loginUserAndTokenVo);
        }
        return error("修改失败！");
    }

}